﻿using LCA.Community.DAL;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Linq;
using LCA.Community.DAL.Model;
using LCA.Community.DAL.Interfaces;
using System.Collections.Generic;
using LCA.Community.DAL.Test.ModelFactories;
using Microsoft.Practices.Unity;

namespace LCA.Community.DAL.Test
{
    /// <summary>
    ///This is a test class for PostsRepositoryTest and is intended
    ///to contain all PostsRepositoryTest Unit Tests
    ///</summary>
    [TestClass()]
    public class PostsRepositoryTest : BaseTestClass
    {
        private UsersFactory _usersFactory = new UsersFactory();
        private List<User> _users;
        private PostsFactory _postsFactory = new PostsFactory();
        private List<Post> _posts;
        private CommentsFactory _commentsFactory = new CommentsFactory();
        private List<Comment> _comments;

        /// <summary>
        /// Initializes the test.
        /// </summary>
        [TestInitialize()]
        public void InitializeTest()
        {
            UnityContainerInitializer();

            var usersRepository = _unityContainer.Resolve<IUsersRepository>();
            _users = _usersFactory.CreateList(3);
            _users.ForEach(user => usersRepository.Add(user));

            var postRepository = _unityContainer.Resolve<IPostsRepository>();
            _posts = _postsFactory.CreateList(5,_users[0].RowKey);
            _posts.ForEach(p => postRepository.Add(p));

            var commentsRepository = _unityContainer.Resolve<ICommentsRepository>();
            _comments = new List<Comment> { 
                _commentsFactory.CreateEntity(_posts[0].RowKey,_users[1].RowKey),
                _commentsFactory.CreateEntity(_posts[0].RowKey,_users[2].RowKey),
            };
            _comments.ForEach(comment => commentsRepository.Add(comment));
        }

        /// <summary>
        /// Cleans up the test.
        /// </summary>
        [TestCleanup()]
        public void CleanupTest()
        {
            var usersRepository = _unityContainer.Resolve<IUsersRepository>();
            var postRepository = _unityContainer.Resolve<IPostsRepository>();

            usersRepository.DeleteTestEntities();
            postRepository.DeleteTestEntities();
        }

        /// <summary>
        ///A test for RecentsPosts
        ///</summary>
        [TestMethod()]
        public void RecentsPostsTest()
        {
            var target = _unityContainer.Resolve<IPostsRepository>();
            var posts = _postsFactory.CreateList(10, _users[0].RowKey);
            posts.ForEach(p => target.Add(p));
            posts.OrderByDescending(p => p.Date);

            List<Post> actual;
            actual = target.RecentsPosts;
            CollectionAssert.AreEquivalent(posts,actual);
        }

        /// <summary>
        ///A test for GetPostByUser
        ///</summary>
        [TestMethod()]
        public void GetPostByUserTest()
        {
            var target = _unityContainer.Resolve<IPostsRepository>();
            string userID = _users[0].RowKey;
            List<Post> expected = _posts;
            List<Post> actual;

            actual = target.GetPostByUser(userID);
            CollectionAssert.AreEquivalent(expected, actual);
        }

        /// <summary>
        ///A test for DeleteAllUserPosts
        ///</summary>
        [TestMethod()]
        public void DeleteAllUserPostsTest()
        {
            var target = _unityContainer.Resolve<IPostsRepository>();
            string user = _users[0].RowKey;
            target.DeleteAllUserPosts(user);

            var actual = target.GetPostByUser(user);
            CollectionAssert.AreEquivalent(new List<Post>(), actual);
        }

        /// <summary>
        ///A test for Delete
        ///</summary>
        [TestMethod()]
        public void DeleteTest()
        {
            var target = _unityContainer.Resolve<IPostsRepository>();
            var commentsRepository = _unityContainer.Resolve<ICommentsRepository>();
            Post entity = _posts[0];
            target.Delete(entity);

            var actual = target.Get(entity.RowKey);
            Assert.IsNull(actual);

            var comments = commentsRepository.GetCommentsByPost(entity.RowKey);
            CollectionAssert.AreEquivalent(new List<Comment>(), comments);
        }
    }
}
